{
  "openapi": "3.1.0",
  "info": {
    "title": "Shared Resources Open API",
    "description": "Manage shared resources (proxies, groups, and tags) through the MoreLogin Open API.\n\n**Base URL**: `https://api.morelogin.com`\n\nAuthentication is done via OAuth2 Bearer token. See [Authentication](../Getting%20Started/authentication.md) for details.\n",
    "version": "2026-09-05"
  },
  "tags": [
    {
      "name": "Proxy Management",
      "description": "Create, update, delete, and list proxy configurations"
    },
    {
      "name": "Group Management",
      "description": "Create, update, delete, and list environment groups"
    },
    {
      "name": "Tag Management",
      "description": "Create, update, delete, and list environment tags"
    },
    {
      "name": "Webhook Management",
      "description": "Configure the team callback endpoint that receives webhook events"
    }
  ],
  "paths": {
    "/proxyInfo/page": {
      "post": {
        "summary": "Getting a list of proxies",
        "deprecated": false,
        "description": "List the team's proxy configurations, page by page.\n\n- **Effect**: none. Read-only. Safe to retry with bounded backoff.\n- **Note**: passwords are withheld from ordinary members and for cloud and dynamic proxies. Dynamic proxies appear here but are managed elsewhere and cannot be edited through the proxy endpoints.",
        "operationId": "queryProxyInfoPageUsingPOST",
        "tags": [
          "Proxy Management"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "pattern": "^\\d+$",
                    "description": "Optional proxy ID for an exact match. Send the 64-bit ID as a decimal string to avoid precision loss. Omit it to query without an ID filter. Other filters and pagination still apply.",
                    "example": "1800000000000101"
                  },
                  "pageNo": {
                    "type": "integer",
                    "description": "Current page number (starts from 1)",
                    "example": 1
                  },
                  "pageSize": {
                    "type": "integer",
                    "description": "Number of items per page",
                    "example": 10
                  },
                  "isCloudPhoneProxy": {
                    "type": "boolean",
                    "description": "Whether the proxy is for cloud phone usage.\n- `true`: Exclude local/private IPs (e.g., 127.0.0.1, 360, pia, private ranges)\n- `false`: Return all proxies\n",
                    "example": false
                  },
                  "proxyCategoryType": {
                    "type": "integer",
                    "description": "Proxy category type:\n- `1` = Cloud platform\n- `2` = Self-owned IP\n",
                    "example": 2
                  },
                  "proxyIp": {
                    "type": "string",
                    "description": "Filter by proxy IP address (partial match)",
                    "example": ""
                  },
                  "proxyName": {
                    "type": "string",
                    "description": "Filter by proxy name (partial match)",
                    "example": ""
                  },
                  "proxyProviders": {
                    "type": "array",
                    "items": {
                      "type": "integer"
                    },
                    "description": "List of Proxy type IDs. Supported values:\n- `0` = None\n- `4` = Oxylabs\n- `5` = Proxys.io\n- `6` = GeoSurf\n- `7` = Luminati\n- `8` = Lumauto\n- `9` = Oxylabsauto\n- `10` = Trojan\n- `11` = Shadowsocks\n- `12` = vmess\n- `13` = ABCPROXY\n- `14` = LunaProxy\n- `15` = IPHTML\n- `16` = PiaProxy\n- `17` = 922S5\n",
                    "example": []
                  },
                  "proxyStatus": {
                    "type": "integer",
                    "description": "Proxy assignment status:\n- `0` = Normal\n- `1` = Unassigned\n- `2` = Upgrading\n- `3` = Expired\n- `4` = Expiring soon  \n> Note: Self-owned proxies always use status `1`.\n",
                    "example": 1
                  },
                  "proxyCheckStatus": {
                    "type": "integer",
                    "description": "Proxy health check status:\n- `0` = Pending\n- `1` = Success\n- `2` = Failed\n- `3` = Unknown error\n",
                    "example": 1
                  },
                  "proxyTypes": {
                    "type": "array",
                    "items": {
                      "type": "integer"
                    },
                    "description": "Proxy protocol types:\n- `0` = HTTP\n- `1` = HTTPS\n- `2` = SOCKS5\n- `3` = SSH\n",
                    "example": []
                  }
                },
                "required": []
              },
              "example": {
                "id": "1800000000000101",
                "pageNo": 1,
                "pageSize": 10,
                "isCloudPhoneProxy": false,
                "proxyCategoryType": 2,
                "proxyIp": "",
                "proxyName": "",
                "proxyProviders": [],
                "proxyStatus": 1,
                "proxyCheckStatus": 1,
                "proxyTypes": []
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success. `data.dataList` holds the records for the requested page and is an empty array when there are no matches; `data.total`, `data.current` and `data.pages` describe the paging.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Return result code 0:Normal Other codes are exceptions.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "Error message",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "current": {
                          "type": "string"
                        },
                        "dataList": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "expiryTime": {
                                "description": "Expiration time",
                                "type": "string"
                              },
                              "id": {
                                "description": "Primary key",
                                "type": "string"
                              },
                              "proxyCategoryType": {
                                "description": "Proxy type 1:Platform proxy; 2:Self-owned proxy",
                                "type": "integer"
                              },
                              "proxyCheckStatus": {
                                "description": "Detection status 0-pending detection 1-monitoring success 2-detection failure 3-unknown error",
                                "type": "integer"
                              },
                              "state": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Proxy state or province. Uses detected exit-IP location when available, otherwise the configured location; may be null or empty.",
                                "example": "California"
                              },
                              "city": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Proxy city. Uses detected exit-IP location when available, otherwise the configured location; may be null or empty.",
                                "example": "Los Angeles"
                              },
                              "proxyPort": {
                                "type": [
                                  "integer",
                                  "null"
                                ],
                                "format": "int32",
                                "description": "Proxy connection port, not a port inferred from the proxy name. May be null when unavailable.",
                                "example": 1080
                              },
                              "proxyIp": {
                                "description": "Proxy IP",
                                "type": "string"
                              },
                              "exportIp": {
                                "description": "export IP",
                                "type": "string"
                              },
                              "countryCode": {
                                "description": "countryCode",
                                "type": "string"
                              },
                              "proxyName": {
                                "description": "Proxy Name",
                                "type": "string"
                              },
                              "proxyProvider": {
                                "description": "Proxy type:default value 0 - none 4-Oxylabs 5-Proxys.io 7-Luminati 8-Lumauto 9-Oxylabsauto 10-Trojan，11-Shadowsocks 13-ABCPROXY 14-LunaProxy 15-IPHTML 16-PiaProxy 17-922S5\n",
                                "type": "integer"
                              },
                              "proxyType": {
                                "description": "Proxy Type:0-http 1-https 2-socks5 3-ssh",
                                "type": "integer"
                              },
                              "username": {
                                "description": "Proxy username",
                                "type": "string"
                              },
                              "password": {
                                "description": "Proxy password",
                                "type": "string"
                              },
                              "refreshUrl": {
                                "description": "Proxy refresh URL",
                                "type": "string"
                              }
                            }
                          }
                        },
                        "pages": {
                          "type": "string"
                        },
                        "total": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "current",
                        "dataList",
                        "pages",
                        "total"
                      ]
                    },
                    "requestId": {
                      "description": "Operation Request ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": null,
                  "data": {
                    "current": "1",
                    "dataList": [
                      {
                        "expiryTime": "2026-09-01 12:00:00",
                        "id": "1673823102599682",
                        "proxyCategoryType": 1,
                        "proxyCheckStatus": 1,
                        "state": "California",
                        "city": "Los Angeles",
                        "proxyPort": 1080,
                        "proxyIp": "string",
                        "exportIp": "9222",
                        "countryCode": "string",
                        "proxyName": "example-name",
                        "proxyProvider": 1,
                        "proxyType": 1,
                        "username": "example-name",
                        "password": "string",
                        "refreshUrl": "https://example.com/resource"
                      }
                    ],
                    "pages": "1",
                    "total": "1"
                  },
                  "requestId": "0d8b6f1c-9f4e-4d02-9d1a-7c3f5a1b2c3d"
                }
              }
            },
            "headers": {}
          }
        }
      }
    },
    "/proxyInfo/add": {
      "post": {
        "summary": "Adding proxy",
        "deprecated": false,
        "description": "Create a proxy configuration in the team.\n\n- **Preconditions**: `proxyPort` is required and must be 1–65535, and `proxyProvider` must be a recognised proxy type.\n- **Effect**: inserts a proxy record and returns its id, ready to bind to profiles. This only saves the configuration.\n- **Completion**: synchronous.\n- **Retry**: **there is no name or configuration uniqueness check.** Posting the same body twice produces two proxies with two ids. After a timeout, search `/proxyInfo/page` before resending.\n\nDocumented business errors: `14023`. See [Error Codes](../Getting%20Started/error-codes.md) for what each code means. Any operation can additionally return the common codes.",
        "operationId": "addUsingPOST",
        "tags": [
          "Proxy Management"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "city": {
                    "type": "string",
                    "description": "City",
                    "example": ""
                  },
                  "country": {
                    "type": "string",
                    "description": "Country code (ISO 3166-1 alpha-2). Required only if proxyProvider=17.\n",
                    "example": "AD"
                  },
                  "encryptionType": {
                    "type": "integer",
                    "format": "int32",
                    "description": "Encryption type, valid values are integers from 1 to 14.",
                    "example": 14
                  },
                  "ipChangeAction": {
                    "type": "integer",
                    "format": "int32",
                    "description": "Action on IP change:0 = Block, 1 = Warn",
                    "example": 1
                  },
                  "ipMonitor": {
                    "type": "boolean",
                    "description": "Enable IP change monitoring",
                    "example": false
                  },
                  "password": {
                    "type": "string",
                    "description": "Password for proxy authentication",
                    "example": ""
                  },
                  "proxyIp": {
                    "type": "string",
                    "description": "Proxy IP address",
                    "example": "8.10.22.46"
                  },
                  "proxyName": {
                    "type": "string",
                    "description": "Proxy name (supports placeholders like {{random}})",
                    "example": "sock5_{{random}}"
                  },
                  "proxyPort": {
                    "type": "integer",
                    "format": "int32",
                    "description": "Proxy port number",
                    "example": 65534
                  },
                  "proxyProvider": {
                    "type": "integer",
                    "format": "int32",
                    "description": "Proxy type:\n0=HTTP, 1=HTTPS, 2=SOCKS5, 3=SSH, 4=Oxylabs, 5=Proxys.io, 6=GeoSurf, 7=Luminati, 8=Lumauto, 9=Oxylabsauto, 10=Trojan, 11=Shadowsocks, 12=vmess, 13=ABCPROXY, 14=LunaProxy, 15=IPHTML, 16=PiaProxy, 17=922S5.\nSpecial rules:\n- If proxyProvider is 7 or 8, proxyType is required.\n- If proxyProvider is 17, country is required; state and city are optional.\n",
                    "example": 2
                  },
                  "proxyType": {
                    "type": "integer",
                    "format": "int32",
                    "description": "Proxy protocol type: 0=HTTP, 1=HTTPS, 2=SOCKS5, 3=SSH.\nRequired only when proxyProvider is 7 or 8.\n",
                    "example": 1
                  },
                  "refreshUrl": {
                    "type": "string",
                    "description": "URL to refresh dynamic proxy IP (if supported)",
                    "example": ""
                  },
                  "state": {
                    "type": "string",
                    "description": "State/Province",
                    "example": ""
                  },
                  "username": {
                    "type": "string",
                    "description": "Username for proxy authentication",
                    "example": ""
                  }
                },
                "required": [
                  "proxyIp",
                  "proxyPort",
                  "proxyProvider"
                ]
              },
              "example": {
                "proxyIp": "8.10.22.46",
                "proxyPort": 65534,
                "proxyProvider": 2,
                "proxyType": 1,
                "country": "AD",
                "state": "",
                "city": "",
                "encryptionType": 14,
                "ipChangeAction": 1,
                "ipMonitor": false,
                "proxyName": "sock5_{{random}}",
                "refreshUrl": "",
                "username": "",
                "password": ""
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success. `data` is a single integer value.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Return result code 0:Normal Other codes are exceptions.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "Error message",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "description": "Proxy ID",
                      "type": "integer"
                    },
                    "requestId": {
                      "description": "Operation Request ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": 0,
                  "requestId": "abcd1234"
                }
              }
            },
            "headers": {}
          }
        }
      }
    },
    "/proxyInfo/update": {
      "post": {
        "summary": "Modifying proxy information",
        "deprecated": false,
        "description": "Update a proxy configuration.\n\n- **Preconditions**: the proxy must exist in the team. **Dynamic proxies cannot be updated** through this endpoint. The proxy type must be a recognised value.\n- **Effect**: this is a full overwrite, not a patch — fields you omit fall back to their defaults rather than keeping their current values. Read the proxy first and send it back complete.\n- **Propagation**: profiles keep their binding because only the proxy record changes, but a browser or Cloud Phone that is already running continues to use the connection details it started with. Restart it to pick up the new ones.\n- **Completion**: synchronous. No optimistic locking, so concurrent updates are last-write-wins.\n\nDocumented business errors: `14003`, `14023`. See [Error Codes](../Getting%20Started/error-codes.md) for what each code means. Any operation can additionally return the common codes.",
        "operationId": "updateProxyUsingPOST",
        "tags": [
          "Proxy Management"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "id",
                  "proxyIp",
                  "proxyPort",
                  "proxyProvider"
                ],
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "Unique proxy ID"
                  },
                  "proxyIp": {
                    "type": "string",
                    "description": "Proxy server IP address"
                  },
                  "proxyPort": {
                    "type": "integer",
                    "description": "Proxy server port"
                  },
                  "proxyName": {
                    "type": "string",
                    "description": "Custom name for the proxy"
                  },
                  "country": {
                    "type": "string",
                    "description": "Country (e.g., \"US\", \"CN\")"
                  },
                  "city": {
                    "type": "string",
                    "description": "City name"
                  },
                  "username": {
                    "type": "string",
                    "description": "Authentication username (if required)"
                  },
                  "password": {
                    "type": "string",
                    "description": "Authentication password (if required)"
                  },
                  "proxyType": {
                    "type": "integer",
                    "description": "Proxy protocol type:\n- `0` = HTTP\n- `1` = HTTPS\n- `2` = SOCKS5\n- `3` = SSH\n"
                  },
                  "proxyProvider": {
                    "type": "integer",
                    "description": "Proxy type ID:\n- `0` = HTTP\n- `1` = HTTPS\n- `2` = SOCKS5\n- `3` = SSH\n- `4` = Oxylabs\n- `5` = Proxys.io\n- `6` = GeoSurf\n- `7` = Luminati\n- `8` = Lumauto\n- `9` = Oxylabsauto\n- `10` = Trojan\n- `11` = Shadowsocks\n- `12` = vmess\n- `13` = ABCPROXY\n- `14` = LunaProxy\n- `15` = IPHTML\n- `16` = PiaProxy\n- `17` = 922S5\n"
                  },
                  "encryptionType": {
                    "type": "integer",
                    "description": "Encryption type (type-specific, usually 0 for plain)"
                  },
                  "ipMonitor": {
                    "type": "boolean",
                    "description": "Enable IP change monitoring"
                  },
                  "ipChangeAction": {
                    "type": "integer",
                    "description": "Action to take when IP changes:\n- `1` = Notify / Refresh (common value)\n> Check system documentation for full options.\n"
                  },
                  "refreshUrl": {
                    "type": "string",
                    "description": "URL to trigger IP refresh (if supported by the proxy type)"
                  },
                  "state": {
                    "type": "string",
                    "description": "Reserved field or custom state (optional)"
                  }
                }
              },
              "example": {
                "id": "1566403036579198",
                "proxyIp": "108.11.23.85",
                "proxyPort": 4096,
                "proxyName": "MyProxy",
                "country": "US",
                "city": "New York",
                "username": "",
                "password": "",
                "proxyType": 0,
                "proxyProvider": 0,
                "encryptionType": 0,
                "ipMonitor": true,
                "ipChangeAction": 1,
                "refreshUrl": "",
                "state": ""
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success. This operation returns no payload; the outcome is carried by `code`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Return result code 0:Normal Other codes are exceptions.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "Error message",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "requestId": {
                      "description": "Operation Request ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "requestId": "efgh5678"
                }
              }
            },
            "headers": {}
          }
        }
      }
    },
    "/proxyInfo/delete": {
      "post": {
        "summary": "Delete proxy",
        "deprecated": false,
        "description": "Delete one or more proxy configurations.\n\n- **Preconditions**: at least one id must resolve within the team; ids that do not are ignored silently. **An unexpired cloud-platform proxy cannot be deleted** and is reported with a dedicated error.\n- **Effect**: own proxies are removed and unbound from any jump server. An expired cloud-platform proxy is instead marked for release, its subscription is cancelled, and the IP is released **asynchronously** — the release may still be in flight when the response returns.\n- **Cascade**: profiles and Cloud Phones bound to the proxy are **neither blocked nor unbound**. They keep pointing at the deleted proxy, and running sessions are not interrupted. Rebind them with `/env/setProxy/batch` before deleting.\n- **Retry**: ids are processed one at a time and the call aborts on the first rejection, so a batch can be partially applied. Re-read `/proxyInfo/page` before retrying.\n\nDocumented business errors: `14017`, `14024`. See [Error Codes](../Getting%20Started/error-codes.md) for what each code means. Any operation can additionally return the common codes.",
        "operationId": "deleteProxyUsingPOST",
        "tags": [
          "Proxy Management"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int64"
                }
              },
              "example": [
                1054661322597744600,
                1054661322597744600
              ]
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success. This operation returns no payload; the outcome is carried by `code`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Return result code 0:Normal Other codes are exceptions.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "Error message",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "requestId": {
                      "description": "Operation Request ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "requestId": "ijkl9012"
                }
              }
            },
            "headers": {}
          }
        }
      }
    },
    "/envgroup/page": {
      "post": {
        "operationId": "envgroupPagePost",
        "summary": "Get a list of groups",
        "deprecated": false,
        "description": "List profile groups, page by page.\n\n- **Effect**: none. Read-only. Safe to retry with bounded backoff.\n- **Note**: when the team authorizes access per group, a member who has no group grants receives an empty page rather than an error.",
        "tags": [
          "Group Management"
        ],
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "groupName": {
                    "type": "string",
                    "title": "Group name (partial match)"
                  },
                  "pageNo": {
                    "type": "integer",
                    "title": "Current page"
                  },
                  "pageSize": {
                    "type": "integer",
                    "title": "Items per page"
                  }
                },
                "required": [
                  "groupName",
                  "pageNo",
                  "pageSize"
                ]
              },
              "example": {
                "groupName": "132-kernel",
                "pageNo": 1,
                "pageSize": 10
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success. `data.dataList` holds the records for the requested page and is an empty array when there are no matches; `data.total`, `data.current` and `data.pages` describe the paging.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Return result code 0:Normal Other codes are exceptions.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "Error message",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "current": {
                          "type": "string"
                        },
                        "dataList": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "description": "Group ID",
                                "type": "string"
                              },
                              "groupName": {
                                "description": "Group name",
                                "type": "string"
                              }
                            }
                          }
                        },
                        "pages": {
                          "type": "string"
                        },
                        "total": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "current",
                        "dataList",
                        "pages",
                        "total"
                      ]
                    },
                    "requestId": {
                      "description": "Operation Request ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": {
                    "current": "0",
                    "dataList": [
                      {
                        "id": "0",
                        "groupName": ""
                      }
                    ],
                    "pages": "0",
                    "total": "0"
                  },
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        }
      }
    },
    "/envgroup/edit": {
      "post": {
        "operationId": "envgroupEditPost",
        "summary": "Modify grouping information",
        "deprecated": false,
        "description": "Rename a profile group.\n\n- **Preconditions**: the group must exist in the team, the caller must be authorized for it, and the new name must not collide with another group. The uniqueness check only runs when the name actually changes.\n- **Effect**: renames the group. Profiles stay in it — they reference the group by id, so nothing else has to be updated.\n- **Completion**: synchronous and idempotent.",
        "tags": [
          "Group Management"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "groupName",
                  "id"
                ],
                "properties": {
                  "groupName": {
                    "type": "string",
                    "description": "New name for the environment group"
                  },
                  "id": {
                    "type": "string",
                    "description": "Unique ID of the group to be updated"
                  }
                }
              },
              "example": {
                "groupName": "Group-1574544945848579",
                "id": "1574525425557584"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success. `data` is a single boolean value.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Return result code 0:Normal Other codes are exceptions.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "Error message",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "boolean",
                      "description": "result"
                    },
                    "requestId": {
                      "description": "Operation Request ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": null,
                  "data": true,
                  "requestId": "0d8b6f1c-9f4e-4d02-9d1a-7c3f5a1b2c3d"
                }
              }
            },
            "headers": {}
          }
        }
      }
    },
    "/envgroup/create": {
      "post": {
        "operationId": "envgroupCreatePost",
        "summary": "Add group",
        "deprecated": false,
        "description": "Create a profile group.\n\n- **Preconditions**: the name must be non-empty, at most 100 characters, and not already used by a group in the team. **A team is limited to 1000 groups.**\n- **Effect**: creates the group. When the team authorizes access per group and the caller is not the owner, the caller is also granted access to the new group.\n- **Completion**: synchronous; `data` carries the new group id.\n- **Retry**: a duplicate name is rejected rather than reusing the existing group, so a retry after a successful-but-unseen call fails with a duplicate-name error — that is a signal the first call worked. Confirm with `/envgroup/page`.",
        "tags": [
          "Group Management"
        ],
        "parameters": [],
        "security": [
          {
            "Authorization": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {}
              },
              "example": {}
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success. `data` is an object with the fields `id` and `groupName`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Return result code 0:Normal Other codes are exceptions.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "Error message",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "description": "The data returned by the operation",
                      "type": "object",
                      "properties": {
                        "id": {
                          "description": "ID of group",
                          "type": "string"
                        },
                        "groupName": {
                          "description": "Name of group",
                          "type": "string"
                        }
                      }
                    },
                    "requestId": {
                      "description": "Operation Request ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": null,
                  "data": {
                    "id": "1673823102599682",
                    "groupName": "example-name"
                  },
                  "requestId": "0d8b6f1c-9f4e-4d02-9d1a-7c3f5a1b2c3d"
                }
              }
            },
            "headers": {}
          }
        }
      }
    },
    "/envgroup/delete": {
      "post": {
        "operationId": "envgroupDeletePost",
        "summary": "Delete group",
        "deprecated": false,
        "description": "Delete one or more profile groups.\n\n- **Preconditions**: at least one id must resolve within the team and the caller must be authorized for it; ids that do not resolve are ignored silently.\n- **Effect**: deletes the groups and their member access grants. Browser profiles and Cloud Phones that were in them become ungrouped, so no dangling group reference is left behind. Setting the delete-environments flag additionally moves the profiles you are authorized for **into the recycle bin** — they are not destroyed and Cloud Phones are never affected by that flag.\n- **Completion**: synchronous but **not atomic**. The group is deleted first and the follow-up steps can still fail, for example when a profile is running or mid-transfer, leaving the group gone and the profiles unmoved.\n- **Retry**: verify with `/envgroup/page` and the profile list before retrying.\n\nDocumented business errors: `19064`. See [Error Codes](../Getting%20Started/error-codes.md) for what each code means. Any operation can additionally return the common codes.",
        "tags": [
          "Group Management"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "ids"
                ],
                "properties": {
                  "ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Unique ID of the group to be updated"
                  },
                  "isDeleteAllEnv": {
                    "type": "boolean",
                    "description": "Delete environments in the group? false:Do not delete true:Delete"
                  }
                }
              },
              "example": {
                "ids": [
                  "string"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success. `data` is a single boolean value.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Return result code 0:Normal Other codes are exceptions.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "Error message",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "boolean"
                    },
                    "requestId": {
                      "description": "Operation Request ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": true,
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        }
      }
    },
    "/envtag/all": {
      "get": {
        "operationId": "envtagAllGet",
        "summary": "Getting a list of tags",
        "deprecated": false,
        "description": "Return every profile tag in the team.\n\n- **Effect**: none. Read-only. Safe to retry with bounded backoff.\n- **Note**: this endpoint is **not paginated and tags have no server-side limit**, so the response grows with the number of tags your team has created. Size your client accordingly.",
        "tags": [
          "Tag Management"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success. `data` is an array of objects with the fields `id` and `tagName`, and an empty array when there is nothing to return.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Return result code 0:Normal Other codes are exceptions.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "error message",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "description": "ID of tags",
                            "type": "string"
                          },
                          "tagName": {
                            "description": "Name of tags",
                            "type": "string"
                          }
                        }
                      }
                    },
                    "requestId": {
                      "description": "Operation Request ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": [
                    {
                      "id": "0",
                      "tagName": ""
                    }
                  ],
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        }
      }
    },
    "/envtag/create": {
      "post": {
        "operationId": "envtagCreatePost",
        "summary": "Create tags",
        "deprecated": false,
        "description": "Create a profile tag.\n\n- **Preconditions**: the name must be non-empty, at most 100 characters, and not already used by a tag in the team.\n- **Effect**: creates the tag and returns its id. Unlike groups, tags have no count limit.\n- **Retry**: a duplicate name is rejected rather than reusing the existing tag. Confirm with `/envtag/all`.",
        "tags": [
          "Tag Management"
        ],
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "tagName": {
                    "type": "string",
                    "description": "tag name"
                  }
                }
              },
              "example": {
                "tagName": "Tag-123"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success. `data` is an object with the fields `id` and `tagName`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Return result code 0:Normal Other codes are exceptions.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "error message",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "description": "ID of tags",
                          "type": "string"
                        },
                        "tagName": {
                          "description": "Name of tags",
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "tagName"
                      ]
                    },
                    "requestId": {
                      "description": "Operation Request ID",
                      "type": "string"
                    },
                    "error": {
                      "type": "object",
                      "properties": {}
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": {
                    "id": "0",
                    "tagName": ""
                  },
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        }
      }
    },
    "/envtag/edit": {
      "post": {
        "operationId": "envtagEditPost",
        "summary": "Modify information of tags",
        "deprecated": false,
        "description": "Rename a profile tag.\n\n- **Preconditions**: the tag must exist in the team, and the new name must not collide with another tag.\n- **Effect**: renames the tag. Existing tag assignments are unaffected and profiles show the new name immediately.\n- **Completion**: synchronous and idempotent.",
        "tags": [
          "Tag Management"
        ],
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "tag id"
                  },
                  "tagName": {
                    "type": "string",
                    "description": "tag name"
                  }
                }
              },
              "example": {
                "id": "1564715845550177",
                "tagName": "Updated-123"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success. `data` is a single boolean value.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Return result code 0:Normal Other codes are exceptions.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "Error message",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "boolean"
                    },
                    "requestId": {
                      "description": "Operation Request ID",
                      "type": "string"
                    },
                    "error": {
                      "type": "object",
                      "properties": {}
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": true,
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        }
      }
    },
    "/envtag/delete": {
      "post": {
        "operationId": "envtagDeletePost",
        "summary": "Delete tags",
        "deprecated": false,
        "description": "Delete one or more profile tags.\n\n- **Preconditions**: at least one id must resolve within the team; ids that do not are ignored silently.\n- **Effect**: deletes the tags. The tag disappears from every profile that carried it, and no profile is deleted. This endpoint only manages profile tags — Cloud Storage file tags are managed separately.\n- **Completion**: synchronous. A repeat call reports the tags as invalid, which means the first one succeeded.\n\nDocumented business errors: `19105`. See [Error Codes](../Getting%20Started/error-codes.md) for what each code means. Any operation can additionally return the common codes.",
        "tags": [
          "Tag Management"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "ids"
                ],
                "properties": {
                  "ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Unique ID of the tag to be updated"
                  }
                }
              },
              "example": {
                "ids": [
                  "string"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success. `data` is a single boolean value.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Return result code 0:Normal Other codes are exceptions.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "Error message",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "boolean"
                    },
                    "requestId": {
                      "description": "Operation Request ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": true,
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        }
      }
    },
    "/webhook/config": {
      "post": {
        "operationId": "webhookConfigPost",
        "summary": "Configure the team webhook",
        "deprecated": false,
        "description": "Create or replace the team's webhook configuration.\n\n- **Preconditions**: `callbackUrl` must be an HTTPS URL of 1 to 1024 characters, with a host, no user info, no fragment and a valid port. Every address it resolves to must be publicly routable; localhost, private, link-local, CGNAT, cloud metadata, protocol-reserved, documentation and 6to4 ranges are rejected. The same check runs again when a delivery opens its connection, so a name that later resolves into a private range fails that delivery instead of reaching your network.\n- **Effect**: upserts the single configuration owned by the team in the server-side context. `teamId` is never read from the request, so a caller cannot configure another team. The Local API and Open API endpoints read and write the same record, and the response echoes what was stored.\n- **Disabling**: `enabled: false` keeps the URL and stops new events from being created. Events already queued are cancelled one by one if the configuration is still disabled when they are next authorized, so re-enabling quickly lets them continue.\n- **Retry**: safe. The save is an upsert keyed by team, so repeating the same request converges on the same state.\n\nSee [Webhooks](../Getting%20Started/webhooks.md) for the callback contract, event names and retry schedule.\n\nDocumented business errors: `41001`. See [Error Codes](../Getting%20Started/error-codes.md) for what each code means. Any operation can additionally return the common codes.",
        "tags": [
          "Webhook Management"
        ],
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "callbackUrl": {
                    "description": "HTTPS URL that receives the events. 1 to 1024 characters.",
                    "type": "string",
                    "maxLength": 1024
                  },
                  "enabled": {
                    "description": "Whether delivery is enabled for the team.",
                    "type": "boolean"
                  }
                },
                "required": [
                  "callbackUrl",
                  "enabled"
                ]
              },
              "example": {
                "callbackUrl": "https://example.com/morelogin/webhook",
                "enabled": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success. `data` is an object with the fields `callbackUrl` and `enabled`, echoing the stored configuration.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Return result code 0:Normal Other codes are exceptions.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "error message",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "callbackUrl": {
                          "description": "The stored HTTPS callback URL.",
                          "type": "string"
                        },
                        "enabled": {
                          "description": "Whether delivery is enabled for the team.",
                          "type": "boolean"
                        }
                      }
                    },
                    "requestId": {
                      "description": "Operation Request ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": {
                    "callbackUrl": "https://example.com/morelogin/webhook",
                    "enabled": true
                  },
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        }
      }
    }
  },
  "webhooks": {
    "cloud_phone.power_on": {
      "post": {
        "operationId": "webhookCloudPhonePowerOn",
        "summary": "Cloud phone power on finished",
        "description": "Sent once a power-on reached its final result.\n\n`success` is `true` only when the completion callback succeeded and the local synchronisation committed. A billing failure, or an asynchronous proxy check that fails and finishes its cleanup, reports a failed power on and does not emit a separate power off. Deferred work such as installing preset apps does not change the result.\n\nIf a power off interrupts the boot, no power-on event is produced for that attempt; the later successful shutdown still produces its own `cloud_phone.power_off`.",
        "tags": [
          "Webhook Management"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventId"
          },
          {
            "$ref": "#/components/parameters/WebhookEventType"
          },
          {
            "$ref": "#/components/parameters/WebhookUserAgent"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CloudPhoneWebhookEvent"
              },
              "example": {
                "eventId": "c7f3a2b10d8e4f6a9c1b2d3e4f5a6b7c",
                "eventType": "cloud_phone.power_on",
                "eventTime": "1787241600000",
                "data": {
                  "teamId": "10001",
                  "cloudPhoneId": "20001"
                },
                "result": {
                  "success": false,
                  "code": "33318",
                  "message": "Operation failed"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "cloud_phone.power_off": {
      "post": {
        "operationId": "webhookCloudPhonePowerOff",
        "summary": "Cloud phone powered off",
        "description": "Sent when a shutdown succeeded. A failed shutdown does not produce this event, so `result.success` is always `true` here.\n\n`data.reason` records why the phone stopped.",
        "tags": [
          "Webhook Management"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventId"
          },
          {
            "$ref": "#/components/parameters/WebhookEventType"
          },
          {
            "$ref": "#/components/parameters/WebhookUserAgent"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CloudPhonePowerOffWebhookEvent"
              },
              "example": {
                "eventId": "5b1d0c9e7a2f4d38b6c5a4e3f2d1c0b9",
                "eventType": "cloud_phone.power_off",
                "eventTime": "1787241600000",
                "data": {
                  "teamId": "10001",
                  "cloudPhoneId": "20001",
                  "reason": "MONEY_SAVING"
                },
                "result": {
                  "success": true,
                  "code": "0",
                  "message": null
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "cloud_phone.restart": {
      "post": {
        "operationId": "webhookCloudPhoneRestart",
        "summary": "Cloud phone restart finished",
        "description": "Sent once a restart reached its final result. `success` is `true` only when the completion callback succeeded and the local synchronisation committed.",
        "tags": [
          "Webhook Management"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventId"
          },
          {
            "$ref": "#/components/parameters/WebhookEventType"
          },
          {
            "$ref": "#/components/parameters/WebhookUserAgent"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CloudPhoneWebhookEvent"
              },
              "example": {
                "eventId": "9e4c1a7b3f2d40518a6b5c4d3e2f1a0b",
                "eventType": "cloud_phone.restart",
                "eventTime": "1787241600000",
                "data": {
                  "teamId": "10001",
                  "cloudPhoneId": "20001"
                },
                "result": {
                  "success": true,
                  "code": "0",
                  "message": null
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "cloud_phone.reset": {
      "post": {
        "operationId": "webhookCloudPhoneReset",
        "summary": "Cloud phone reset finished",
        "description": "Sent once a reset reached its final result. `success` is `true` only when the completion callback succeeded and the local synchronisation committed.",
        "tags": [
          "Webhook Management"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventId"
          },
          {
            "$ref": "#/components/parameters/WebhookEventType"
          },
          {
            "$ref": "#/components/parameters/WebhookUserAgent"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CloudPhoneWebhookEvent"
              },
              "example": {
                "eventId": "2f8a6d4c0b9e47138c7d6e5f4a3b2c1d",
                "eventType": "cloud_phone.reset",
                "eventTime": "1787241600000",
                "data": {
                  "teamId": "10001",
                  "cloudPhoneId": "20001"
                },
                "result": {
                  "success": true,
                  "code": "0",
                  "message": null
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "cloud_phone.new_machine": {
      "post": {
        "operationId": "webhookCloudPhoneNewMachine",
        "summary": "Cloud phone one-click new machine finished",
        "description": "Sent once a one-click new machine operation reached its final result. `success` is `true` only when the completion callback succeeded and the local synchronisation committed.",
        "tags": [
          "Webhook Management"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventId"
          },
          {
            "$ref": "#/components/parameters/WebhookEventType"
          },
          {
            "$ref": "#/components/parameters/WebhookUserAgent"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CloudPhoneWebhookEvent"
              },
              "example": {
                "eventId": "7c3b1e9d5a4f42068b1c2d3e4f5a6b70",
                "eventType": "cloud_phone.new_machine",
                "eventTime": "1787241600000",
                "data": {
                  "teamId": "10001",
                  "cloudPhoneId": "20001"
                },
                "result": {
                  "success": true,
                  "code": "0",
                  "message": null
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "cloud_browser.start": {
      "post": {
        "operationId": "webhookCloudBrowserStart",
        "summary": "Cloud browser start finished",
        "description": "Sent once a cloud browser start reached its final result.",
        "tags": [
          "Webhook Management"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventId"
          },
          {
            "$ref": "#/components/parameters/WebhookEventType"
          },
          {
            "$ref": "#/components/parameters/WebhookUserAgent"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CloudBrowserWebhookEvent"
              },
              "example": {
                "eventId": "4a9f2c7e1b8d43509c6a5b4c3d2e1f00",
                "eventType": "cloud_browser.start",
                "eventTime": "1787241600000",
                "data": {
                  "teamId": "10001",
                  "cloudBrowserId": "30001",
                  "runId": "40001"
                },
                "result": {
                  "success": true,
                  "code": "0",
                  "message": null
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "cloud_browser.stop": {
      "post": {
        "operationId": "webhookCloudBrowserStop",
        "summary": "Cloud browser stop finished",
        "description": "Sent for every cloud browser stop attempt, successful or not. Reaching the stop-failed state is itself a failed result for that attempt; a later manual retry or forced release counts as a new operation and produces a new `eventId`.\n\nEvents are deduplicated per stop operation, so one attempt never yields two events and two attempts are never merged. An internal archiving failure changes only `result`; it never overwrites the `reason` captured when the stop began.",
        "tags": [
          "Webhook Management"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventId"
          },
          {
            "$ref": "#/components/parameters/WebhookEventType"
          },
          {
            "$ref": "#/components/parameters/WebhookUserAgent"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CloudBrowserStopWebhookEvent"
              },
              "example": {
                "eventId": "c7f3a2b10d8e4f6a9c1b2d3e4f5a6b7c",
                "eventType": "cloud_browser.stop",
                "eventTime": "1787241600000",
                "data": {
                  "teamId": "10001",
                  "cloudBrowserId": "30001",
                  "runId": "40001",
                  "reason": "BROWSER_EXITED"
                },
                "result": {
                  "success": false,
                  "code": "40006",
                  "message": "Operation failed"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "Authorization": {
        "type": "http",
        "description": "Token for request access token interface response access_token field",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      }
    },
    "parameters": {
      "WebhookEventId": {
        "name": "X-Webhook-Event-Id",
        "in": "header",
        "required": true,
        "description": "Same value as `eventId` in the body. Use it to make your handler idempotent.",
        "schema": {
          "type": "string"
        }
      },
      "WebhookEventType": {
        "name": "X-Webhook-Event-Type",
        "in": "header",
        "required": true,
        "description": "Same value as `eventType` in the body, so you can route without parsing.",
        "schema": {
          "type": "string"
        }
      },
      "WebhookUserAgent": {
        "name": "User-Agent",
        "in": "header",
        "required": true,
        "description": "Always `MoreLogin-Webhook/1.0`.",
        "schema": {
          "type": "string"
        }
      }
    },
    "responses": {
      "WebhookAck": {
        "description": "Any 2xx is treated as delivered. The response body is ignored, so return as early as you can and do the work asynchronously. Anything else, including a connection or read timeout, counts as a failure and is retried."
      }
    },
    "schemas": {
      "WebhookResult": {
        "type": "object",
        "description": "The final outcome of the operation the event describes.",
        "properties": {
          "success": {
            "description": "Whether the operation ultimately succeeded.",
            "type": "boolean"
          },
          "code": {
            "description": "`0` on success. On failure, a stable business error code that does not depend on language.",
            "type": "string"
          },
          "message": {
            "description": "`null` on success. On failure, an explanation in the team's language, falling back to `en-US` when that language or its text is unavailable.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "success",
          "code",
          "message"
        ]
      },
      "CloudPhoneWebhookEvent": {
        "type": "object",
        "properties": {
          "eventId": {
            "description": "Unique event ID. Delivery retries and internal replays of the same event reuse it, so treat it as the idempotency key.",
            "type": "string"
          },
          "eventType": {
            "description": "Stable event name.",
            "type": "string"
          },
          "eventTime": {
            "description": "When the final business result happened, as Unix epoch milliseconds. Sent as a string.",
            "type": "string"
          },
          "data": {
            "type": "object",
            "properties": {
              "teamId": {
                "description": "The team that owns the resource.",
                "type": "string"
              },
              "cloudPhoneId": {
                "description": "The cloud phone the event is about.",
                "type": "string"
              }
            },
            "required": [
              "teamId",
              "cloudPhoneId"
            ]
          },
          "result": {
            "$ref": "#/components/schemas/WebhookResult"
          }
        },
        "required": [
          "eventId",
          "eventType",
          "eventTime",
          "data",
          "result"
        ]
      },
      "CloudPhonePowerOffWebhookEvent": {
        "type": "object",
        "properties": {
          "eventId": {
            "description": "Unique event ID. Delivery retries and internal replays of the same event reuse it, so treat it as the idempotency key.",
            "type": "string"
          },
          "eventType": {
            "description": "Stable event name.",
            "type": "string"
          },
          "eventTime": {
            "description": "When the final business result happened, as Unix epoch milliseconds. Sent as a string.",
            "type": "string"
          },
          "data": {
            "type": "object",
            "properties": {
              "teamId": {
                "description": "The team that owns the resource.",
                "type": "string"
              },
              "cloudPhoneId": {
                "description": "The cloud phone the event is about.",
                "type": "string"
              },
              "reason": {
                "description": "Why the phone stopped.",
                "type": "string",
                "enum": [
                  "NORMAL",
                  "MONEY_SAVING",
                  "OTHER"
                ]
              }
            },
            "required": [
              "teamId",
              "cloudPhoneId",
              "reason"
            ]
          },
          "result": {
            "$ref": "#/components/schemas/WebhookResult"
          }
        },
        "required": [
          "eventId",
          "eventType",
          "eventTime",
          "data",
          "result"
        ]
      },
      "CloudBrowserWebhookEvent": {
        "type": "object",
        "properties": {
          "eventId": {
            "description": "Unique event ID. Delivery retries and internal replays of the same event reuse it, so treat it as the idempotency key.",
            "type": "string"
          },
          "eventType": {
            "description": "Stable event name.",
            "type": "string"
          },
          "eventTime": {
            "description": "When the final business result happened, as Unix epoch milliseconds. Sent as a string.",
            "type": "string"
          },
          "data": {
            "type": "object",
            "properties": {
              "teamId": {
                "description": "The team that owns the resource.",
                "type": "string"
              },
              "cloudBrowserId": {
                "description": "The cloud browser profile the event is about.",
                "type": "string"
              },
              "runId": {
                "description": "The run instance the event is about.",
                "type": "string"
              }
            },
            "required": [
              "teamId",
              "cloudBrowserId",
              "runId"
            ]
          },
          "result": {
            "$ref": "#/components/schemas/WebhookResult"
          }
        },
        "required": [
          "eventId",
          "eventType",
          "eventTime",
          "data",
          "result"
        ]
      },
      "CloudBrowserStopWebhookEvent": {
        "type": "object",
        "properties": {
          "eventId": {
            "description": "Unique event ID. Delivery retries and internal replays of the same event reuse it, so treat it as the idempotency key.",
            "type": "string"
          },
          "eventType": {
            "description": "Stable event name.",
            "type": "string"
          },
          "eventTime": {
            "description": "When the final business result happened, as Unix epoch milliseconds. Sent as a string.",
            "type": "string"
          },
          "data": {
            "type": "object",
            "properties": {
              "teamId": {
                "description": "The team that owns the resource.",
                "type": "string"
              },
              "cloudBrowserId": {
                "description": "The cloud browser profile the event is about.",
                "type": "string"
              },
              "runId": {
                "description": "The run instance the event is about.",
                "type": "string"
              },
              "reason": {
                "description": "Why the run stopped.",
                "type": "string",
                "enum": [
                  "NORMAL",
                  "MONEY_SAVING",
                  "ENERGY_SAVING",
                  "BROWSER_EXITED",
                  "OTHER"
                ]
              }
            },
            "required": [
              "teamId",
              "cloudBrowserId",
              "runId",
              "reason"
            ]
          },
          "result": {
            "$ref": "#/components/schemas/WebhookResult"
          }
        },
        "required": [
          "eventId",
          "eventType",
          "eventTime",
          "data",
          "result"
        ]
      }
    }
  },
  "servers": [
    {
      "url": "https://api.morelogin.com",
      "description": "MoreLogin open api endpoint"
    }
  ],
  "security": [
    {
      "Authorization": []
    }
  ]
}